<?php
namespace Home\Controller;

/*
用户权限管理控制器，使用Auth类
*/
class AuthController extends CommonController {
    //获取用户列表
    public function user(){
        //总数
        $userConn = M('user');
        $data['total'] = $userConn->count();
        
        //数据
        $data['data'] = $userConn->field(array('id', 'username'))->limit(I('get.start') .','. I('get.limit'))->select();
        $this->ajaxReturn($data);
    }

    // 获取规则列表
    public function rule(){
        //总数
        $ruleConn = M('auth_rule');
        $where['del'] = array('eq', '0');//del字段设置的是enum，字符串
        $where['status'] = array('eq', 1);//status字段设置的是tinyint
        $data['total'] = $ruleConn->where($where)->count();
        
        //数据
        $data['data'] = $ruleConn->field('del', true)->where($where)->order('id ASC')->limit(I('get.start') .','. I('get.limit'))->select();
        $this->ajaxReturn($data);
    }

    // 获取用户组列表
    public function group(){
        //总数
        $groupConn = M('auth_group');
        $data['total'] = $groupConn->where(array('del' => array('eq' ,'0')))->count();
        
        //数据
        $data['data'] = $groupConn->where(array('del' => array('eq' ,'0')))->order('id ASC')->field(array('id', 'title', 'status'))->limit(I('get.start') .','. I('get.limit'))->select();
        $this->ajaxReturn($data);
    }

    // 给用户设置用户组
    public function userGroup(){
        // 如果没有传递action，报错返回。由于有普通ajax请求和表单submit提交两种，所以需要success的返回值
        if (!I('post.action', '')) {
            $this->ajaxReturn(array('success' => false, 'msg' => '请求错误，请确认无误后重试~'));
        }
        // 在给用户设置用户组之前，需要先获取所有用户组和它已经所属的用户组
        if (I('post.action') == 'getGroup') {
            // 如果没有传递uid，报错返回。不是表单submit请求的，返回中可以不带success键值对        
            if (!I('post.uid', 0, 'intval')) {
                $this->ajaxReturn(array('msg' => '请选择一个用户~'));
            }

            // 所有的有效的用户组
            $where['del'] = array('eq', '0');//del字段设置的是enum，字符串
            $where['stauts'] = array('eq', 1);//status字段设置的是tinyint
            $groups = M('auth_group')->field('id, title')->where($where)->select();

            // 该用户组已经属于的用户组
            $where2['uid'] = I('post.uid', 0, 'intval');
            // 由于可能属于多个组，所以不能find
            // $hasRules = M('auth_group_access')->field('group_id')->where($where2)->select();

// $this->ajaxReturn(M('auth_group_access')->where($where2)->fetchSql(true)->getField('group_id', true));
//结果中没有key，只有值。结果是索引数组，即使只有一个结果，也是数组。
// "SELECT `group_id` FROM `tbl_auth_group_access` WHERE `uid` = 1 "
            $belongsGroup = M('auth_group_access')->where($where2)->getField('group_id', true);

            if ($belongsGroup) {
                //在所有用户组中遍历，如果是已经属于的用户组，设置属性checked：true，否则false
                foreach ($groups as $k => $v) {
                    // 如果in_array真，则已属于该用户组
                    if (in_array($v['id'], $belongsGroup)) {
                        // 设置选中
                        $groups[$k]['checked'] = true;
                    }else{
                        // 设置不选中
                        $groups[$k]['checked'] = false;
                    }                
                }
            }
            
            $this->ajaxReturn($groups);

        }elseif (I('post.action') == 'setGroup') {
            // 这里表示表单提交，进行数据库更新
            // 前台如果传递了uid参数，表示进行修改。即使某个用户组一开始没有rules，也是修改操作，而不是新增
            if (!I('post.uid', 0, 'intval')) {
                $this->ajaxReturn(array('msg' => '请求错误，请确认无误后重试~'));
            }
            // 给用户组分配的规则id数组
            $idsArray = I('post.userGroupIds');
            // 由于接收到的无序，所以进行从小到大排序。这个并不是必须的，只是为了便于查看结果。
            sort($idsArray, SORT_NUMERIC);
            // 用户id
            $uid = I('post.uid', 0, 'intval');
            // 每个用户组都与该用户id对应，可能会有多条记录
            for ($i=0; $i < count($idsArray); $i++) { 
                $insertArray[$i]['uid'] = $uid;
                $insertArray[$i]['group_id'] = $idsArray[$i];
            }

            // 由于auth_group_access表中没有主键，所以需要先删除原来的用户与用户组对应关系，再重新加入新的对应关系
            M('auth_group_access')->where(array('uid' => array('eq', $uid)))->delete();

            // 新增数据表记录
            if (M('auth_group_access')->addAll($insertArray)) {
                $this->ajaxReturn(array('success' => true, 'msg' => '设置用户组成功~'));
            }
            $this->ajaxReturn(array('success' => false, 'msg' => '设置用户组失败，请重试~'));
        }
    }
    
    // 规则操作（增删改）
    public function ruleOperation(){
        $success = array('success' => true, 'msg' => '修改成功~');
        $error = array('success' => false, 'msg' => '参数有误，不知是新增、修改还是删除~' );
        // 如果请求参数中没有action
        if (!I('post.action', '')) {
            $this->ajaxReturn($error);
        }

        //数据库连接
        $ruleConn = M('auth_rule');

        // 添加一个规则，或者修改某个规则
        if ( I('post.action') == 'addOrModify') {
            
            //如果请求参数中有id，表示修改，否则添加
            //修改
            if (!!I('post.id', 0)) {
                // save方法的返回值是影响的记录数，如果返回false则表示更新出错，因此一定要用恒等来判断是否更新失败。
                if ($ruleConn->data(I('post.'))->save() > 0) {
                    $this->ajaxReturn($success);
                }else{
                    $error['msg'] = '修改规则失败，或者没有任何修改。<br/>请确认修改后再重试~';
                    $this->ajaxReturn($error);
                }
            }else{
                // 添加
                if ($ruleConn->data(I('post.'))->add()) {
                    $success['msg'] = '添加规则成功~';
                    $this->ajaxReturn($success);
                }else{
                    $error['msg'] = '添加规则失败，请重试~';
                    $this->ajaxReturn($error);
                }
            }
        }

        // 删除一个或多个规则
        if ( I('post.action') == 'remove') {
            // 把del设为1 代替真正删除
            $data[id] = array('in', I('post.ids'));
            $data['del'] = '1';
            if ($ruleConn->data($data)->save() > 0) {
                $success['msg'] = '删除规则成功~';
                $this->ajaxReturn($success);
            }else{
                $errorMsg = '删除规则失败，请重试~';
                $this->ajaxReturn($error);
            }
        }        
    }

    // 用户组操作（增删改）
    public function groupOperation(){
        $success = array('success' => true, 'msg' => '修改成功~');
        $error = array('success' => false, 'msg' => '参数有误，不知是新增、修改还是删除~' );
        // 如果请求参数中没有action
        if (I('post.action', '') == '') {
            $this->ajaxReturn($error);
        }

        //数据库连接
        $groupConn = M('auth_group');

        // 添加一个用户组，或者修改某个用户组
        if ( I('post.action') == 'addOrModify') {
            
            //如果请求参数中有id，表示修改，否则添加
            //修改
            if (!!I('post.id', 0)) {
                // save方法的返回值是影响的记录数，如果返回false则表示更新出错，因此一定要用恒等来判断是否更新失败。
                if ($groupConn->data(I('post.'))->save() > 0) {
                    $this->ajaxReturn($success);
                }else{
                    $error['msg'] = '修改用户组失败，或者没有任何修改。<br/>请确认修改后再重试~';
                    $this->ajaxReturn($error);
                }
            }else{
                // 添加
                if ($groupConn->data(I('post.'))->add()) {
                    $success['msg'] = '添加用户组成功~';
                    $this->ajaxReturn($success);
                }else{
                    $error['msg'] = '添加用户组失败，请重试~';
                    $this->ajaxReturn($error);
                }
            }
        }

        // 删除一个或多个用户组
        if ( I('post.action') == 'remove') {
            // 把del设为1 代替真正删除
            $data[id] = array('in', I('post.ids'));
            $data['del'] = '1';
            if ($groupConn->data($data)->save() > 0) {
                $success['msg'] = '删除用户组成功~';
                $this->ajaxReturn($success);
            }else{
                $errorMsg = '删除用户组失败，请重试~';
                $this->ajaxReturn($error);
            }
        }
    }

    // 前台传递请求参数gid--当前用户组的id，要获取所有的规则和该用户组已经拥有的规则，已有规则处于选中
    public function groupRule(){
        // 如果没有传递action，报错返回。由于有普通ajax请求和表单submit提交两种，所以需要success的返回值
        if (!I('post.action', '')) {
            $this->ajaxReturn(array('success' => false, 'msg' => '请求错误，请确认无误后重试~'));
        }
        // 在给用户组分配规则前，需要先获取所有规则和它已拥有权限的规则
        if (I('post.action') == 'getRules') {
            // 如果没有传递gid，报错返回。不是表单submit请求的，返回中可以不带success键值对        
            if (!I('post.gid', 0, 'intval')) {
                $this->ajaxReturn(array('msg' => '请选择一个用户组~'));
            }
            // 所有有效的规则
            $where['del'] = array('eq', '0');//del字段设置的是enum，字符串
            $where['status'] = array('eq', 1);//status字段设置的是tinyint
            $rules = M('auth_rule')->field('id, name, title')->order('id ASC')->where($where)->select();

            // 该用户组已经拥有的规则
            $where2['id'] = I('post.gid', 0, 'intval');
            $where2['status'] = 1;
            $where2['del'] = array('eq' ,'0');
            // 结果是一个id组成的字符串，或者空字符串
            $hasRules = M('auth_group')->field('rules')->where($where2)->find();
            // rules:"1,2,3,9,10,11,53,59,60,61,62,63,64"
            //转为数组
            $hasRuleIdArr = array();
            if ($hasRules && !empty($hasRules)) {
                $hasRuleIdArr = explode(',', $hasRules['rules']);
            }
            //在所有规则中遍历，如果是已经拥有的规则，设置属性checked：true，否则false
            foreach ($rules as $k => $v) {
                // 有时候可能$hasRuleIdArr比较多，每次都进行in_array判断比较耗时。
                // 想法是，当判断已有某个规则了，就把该规则从$hasRuleIdArr中移除，之后再in_array就少些。
                // 也可以不用这么做，只用in_array就可以了。
                // 如果in_array真，则已有该规则
                if (in_array($v['id'], $hasRuleIdArr)) {
                    // 设置选中
                    $rules[$k]['checked'] = true;
                    // 根据id找到$hasRuleIdArr中key
                    $key = array_search($v['id'], $hasRuleIdArr);
                    // 从$hasRuleIdArr中删除该规则
                    array_splice($hasRuleIdArr, $key, 1);
                }else{
                    // 设置不选中
                    $rules[$k]['checked'] = false;
                }                
            }
            $this->ajaxReturn($rules);

        }elseif (I('post.action') == 'setRules') {
            // 这里表示表单提交，进行数据库更新
            // 前台如果传递了id参数，表示进行修改。即使某个用户组一开始没有rules，也是修改操作，而不是新增
            if (!I('post.id', 0, 'intval')) {
                $this->ajaxReturn(array('msg' => '请求错误，请确认无误后重试~'));
            }
            // 给用户组分配的规则id数组
            $idsArray = I('post.ruleIds');
            // 由于接收到的无序，所以进行从小到大排序。这个并不是必须的，只是为了便于查看结果。
            sort($idsArray, SORT_NUMERIC);
            // 连接各元素为字符串
            $data['rules'] = implode(',', $idsArray);
            $data['id'] = I('post.id', 0, 'intval');

            // 更新数据表记录
            if (M('auth_group')->save($data) > 0) {
                $this->ajaxReturn(array('success' => true, 'msg' => '分配权限规则成功~'));
            }
            $this->ajaxReturn(array('success' => false, 'msg' => '分配权限规则失败，请重试~'));
        } 
    }
}